There are two basic plotting strategies for complex networks: the traditional graphical representation, a static view of the topology and structure, and the dynamic visualizations taking advantage of interactivity provided by web access or html widgets (e.g., java-based packages).

Plotting network matrices

There are many functions in R to plot networks, especially unipartite networks. Bipartite networks can readily be plotted with the bipartite package function plotweb (1).

Recently, dynamic extensions of this kind of plot hav been included in package bipartiteD3 (2) (see below).

library(bipartite)
data("Safariland")
plotweb(Safariland)

A function for plotting this type of ‘railway’ diagram is included in my package ggbipart for ploting bipartite networks (see below).

Simple network plotting with ggnet

# Set an example adajcency matrix.
# A weighted adjacency matrix. Rows are animal species; columns are plant 
# species.
library(GGally)
## 
## Attaching package: 'GGally'
## The following object is masked from 'package:dplyr':
## 
##     nasa
bip= data.frame(P1= c(1, 12, 6, 0),
                P2= c(1, 0, 4, 0),
                P3= c(1, 7, 3, 12),
     row.names= letters[1:4])

bip
##   P1 P2 P3
## a  1  1  1
## b 12  0  7
## c  6  4  3
## d  0  0 12
# Initializing the weighted bipartite network
bip.net = network(bip,
              matrix.type = "bipartite",
              ignore.eval = FALSE,
              names.eval = "weights")
bip.net
##  Network attributes:
##   vertices = 7 
##   directed = FALSE 
##   hyper = FALSE 
##   loops = FALSE 
##   multiple = FALSE 
##   bipartite = 4 
##   total edges= 9 
##     missing edges= 0 
##     non-missing edges= 9 
## 
##  Vertex attribute names: 
##     vertex.names 
## 
##  Edge attribute names: 
##     weights

By default, ggnet2 will not do anything particular to the network, treating it as if it were a one-mode network object:

ggnet2(bip.net, label = TRUE)

To use the mode of the nodes as the basis for their colors, just pass the color = "mode" argument, and then to style the "actor" and "event" values:

# Set colors for each mode
col = c("actor" = "grey", "event" = "gold")

# Detect and color the mode
ggnet2(bip.net, color = "mode", palette = col, label = TRUE)

For the weighted network we specify edge.size.

ggnet2(bip.net, color = "mode", palette = col,  label = TRUE, size= 12,
       edge.size= (network::get.edge.attribute(bip.net, "weights"))/2)

Plotting bipartite networks

ggbipart, an R package for plotting bipartite networks

This is a series of R functions aimed to plot bipartite networks within the ggplot2 environment. The library relies heavily on code developed by Francois Briatte for the ggnet library.

If not already installed, just grab it from my GitHub repo. The install will ask to install dependencies packages if new versions of them are available.

# Install directly from the GitHub repository.
require(devtools)

devtools::install_github("pedroj/bipartite_plots", dependencies= T)
library(ggbipart)

Bipartite networks are a special type of network where nodes are of two distinct types or sets, so that connections (links) only exist among nodes of the different sets.

As in other types of network, bipartite strucures can be binary (only the presence/absence of the links is mapped) or quantitative (weighted), where the links can have variable importance or weight.

To plot, we start with an adjacency or incidence matrix. I’m using matrices that illustrate ecological interactions among species, such as the mutualisttic interactions of animal pollinators and plant flowers. The two sets (modes) of these bipartite netwroks are animals (pollinators) ans plants species.

From any adjacency matrix we can get a network object or an igraph object for plotting and analysis.

Here I plot bipartite networks from their adjacency matrices, i.e., the two-mode networks. The standard way to input an adjacency matrix is from a .txt or a .csv file. Most packages like network, igraph or statnet also accept edge-list archives. These have the form of a three-column array with node1 node2 i or node1 node2 w, where node1 and node2 are two nodes that interact, and ior w are the presence/abscence of interaction (i= 0 o r i= 1) or the edge weight (w) in the case of weighted networks.

Initializing bipartite webs as network objects

# Read data matrices.
# Read a network
# Creating the objects. Example input from the clipboard. 
#
# Where data.txt has a weighted adjacency matrix, e.g.,:
    Aa  Ab  Ac  Ba  Bb  Bc  Bd  Ca  Cb  Cc  Da
P1  139 60   9  23  4   104 5   3   5   2   1
P2  184 26  6   10  3   6   17  11  3   1   0
P3  131 74  33  36  13  19  0   9   0   1   0
P4  87  40  38  21  13  0   9   0   1   0   0
P5  100 42  17  12  4   1   1   0   0   0   0
P6  21  15  7   0   4   1   0   0   0   0   0
P7  42  16  3   0   2   0   0   0   0   0   0
P8  31  8   4   5   1   0   0   1   0   0   0
P9  46  8   2   0   3   0   0   0   0   0   0
P10 86  0   0   12  0   2   2   0   0   0   0
P11 23  8   1   5   0   0   0   0   0   0   0
P12 13  6   1   1   0   1   0   0   0   0   0
P13 5   0   1   0   0   0   0   0   0   0   0
P14 9   1   0   0   0   0   0   0   0   0   0

# Use this to copy from the clipboard, after select/copy the above block.
mymat <- read.table(pipe("pbpaste"), header= T, sep= "\t", row.names= 1)

The adjacency matrix is just read from the clipboard as a tab-separated file with header names, and the first column is taken as the row names.

This next example (from F. Briatte code) initializes a dataframe:

# A weighted adjacency matrix. Rows are animal species; columns are plant 
# species.
bip= data.frame(P1= c(1, 12, 6, 0),
                P2= c(1, 0, 4, 0),
                P3= c(1, 7, 3, 12),
     row.names= letters[1:4])

bip
A simple graph

This is a function to plot a classic bipartite graph. In the example above we read the dataset from the clipboard. So now we’ll use a direct reading from a file.

Unweighted
#---------------------------------------------------------------------------
# A function for plotting a traditional bipartite graph
# Plot layout coordinates for railway networkplot
# A matrix whose rows contain the x,y coordinates of the vertices of d.
#
source("./code/functions/bip_init_network.R")
source("./code/functions/bip_init_igraph.R")

bip_railway <- function (mymat, nodesize=9, label=F) {
        # Coords for mode "A"
        coordP<- cbind(rep(2,dim(mymat)[1]), seq(1, dim(mymat)[1])+2)
        # Coords for mode "P"
        coordA<- cbind(rep(4,dim(mymat)[2]), seq(1, dim(mymat)[2])+2)
        mylayout<- as.matrix(rbind(coordP, coordA))
#
# Initialize and plot the network with a railway layout.
        test.net<- bip_init_network(mymat)
        p<- ggnet2(test.net, mode=mylayout, label=label,
                    size= nodesize, label.size=nodesize/3,
                    layout.exp=1.5) +
            coord_flip()
        p
}
#---------------------------------------------------------------------------
#
# Read the matrix again.
mymat <- read.table("./data/data.txt", row.names=1)   # Not run.


# Plot layout coordinates for railway networkplot. Input is the 
# adjacency matrix.
# 
g<- bip_railway(mymat, label=T)
## Loading required package: ggnet
## 
## Attaching package: 'ggnet'
## The following objects are masked from 'package:GGally':
## 
##     ggnet, ggnet2
g+ coord_flip()
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.

To use the mode of the nodes as the basis for their colors, all the user has to do is to pass the color= “mode” argument, and then to style the “actor” and “event” values:

Weighted

Label the edge weights directly into the edges of the graph.

source("./code/functions/bip_ggnet.R")
source("./code/functions/bip_edgewt.R")

bip= data.frame(P1= c(1, 12, 6, 0),
                P2= c(1, 0, 4, 0),
                P3= c(1, 7, 3, 12),
     row.names= letters[1:4])
col= c("A"= "grey80", "P"= "gold2")
bip.net<- bip_init_network(as.matrix(bip)) 

bip_ggnet(bip.net, as.matrix(bip), 
       #  color= "mode", palette = col, 
          edge.label = "weights",
          label= TRUE)
## Warning in guide_merge.legend(init, x[[i]]): Duplicated override.aes is
## ignored.

More complex weighted datsets

These are two example datasets of well-sampled plant-frugivore interaction networks from S Spain, read in the usual way. I also read the attributes files, i.e., data.frames with node characteristics that can be used later to label the nodes.

Note that the matrices are read as data.frames. This is useful for later analysis. Yet it is very handy to have also these adjacency matrices in matrix form.

# The Nava de las Correhuelas dataset.
nch<- read.table("./data/sdw01_adj_fru.csv", 
                  header=T, sep=",", row.names=1,
                  dec=".", na.strings="NA")
## Node attributes
nch_attr<- read.table("./data/sdw01_node_attributes.csv", 
                  header=T, sep=",", 
                  dec=".", na.strings="NA")

# The Hato Raton dataset.
hr<- read.table("./data/sdw02_adj_fru.csv", 
                  header=T, sep=",", row.names=1,
                  dec=".", na.strings="NA")
## Node attributes
hr_attr<- read.table("./data/sdw01_node_attributes.csv", 
                  header=T, sep=",", 
                  dec=".", na.strings="NA")

Node attributes include different variables characterizing each individual node. These values can later be passed to the bip_ggnet funtions to modify graph properties of nodes.

glimpse(nch_attr)
## Observations: 62
## Variables: 26
## $ class   <fct> Magnoliopsida, Liliopsida, Magnoliopsida, Magnoliopsida,…
## $ order   <fct> Rosales, Arales, Ranunculales, Rosales, Rosales, Euphorb…
## $ family  <fct> Rosaceae, Araceae, Berberidaceae, Rosaceae, Rosaceae, Th…
## $ genus   <fct> Amelanchier, Arum, Berberis, Cotoneaster, Crataegus, Dap…
## $ species <fct> Amelanchier.ovalis, Arum.italicum, Berberis.vulgaris, Co…
## $ spcode  <fct> Amova, Arita, Bevul, Cogra, Crmon, Dalau, Hehel, Jucom, …
## $ w       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ g       <dbl> 7.3, 9.2, 5.5, 7.0, 9.3, 6.4, 8.4, 8.6, 12.9, 11.5, 8.7,…
## $ f       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ a       <dbl> 0.00010, 0.66000, 14.52000, 0.14500, 0.84500, 0.00011, 1…
## $ geog    <int> 4, 7, 14, 6, 14, 10, 6, 13, 4, 8, 8, 9, 4, 5, 3, 5, 5, 1…
## $ ph      <dbl> 1.0, 0.5, 3.0, 1.0, 6.0, 1.0, 3.0, 10.0, 2.0, 7.0, 9.0, …
## $ pp      <dbl> 0.3333, 0.2121, 0.2424, 0.3030, 0.1515, 0.2727, 0.2424, …
## $ ps      <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pa      <dbl> 0.1515, 0.1515, 0.1212, 0.0909, 0.1515, 0.2424, 0.0606, …
## $ pu      <dbl> 0.4242, 0.5758, 0.2121, 0.5455, 0.0303, 0.3636, 0.4545, …
## $ hab     <fct> climax, climax, climax, climax, climax, climax, climax, …
## $ diet    <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ forag   <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ noct    <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ nativ   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ frlen   <dbl> 7.0, 11.1, 10.4, 7.5, 12.1, 9.4, 7.2, 8.2, 11.3, 9.9, 7.…
## $ fleshy  <fct> Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Y…
## $ seedm   <dbl> 0.003, 0.038, 0.020, 0.025, 0.124, 0.022, 0.016, 0.011, …
## $ height  <dbl> 1.9, 0.3, 1.2, 1.3, 4.0, 1.2, 3.0, 0.6, 2.8, 0.6, 0.6, 3…
## $ grwform <fct> shrub, herb, shrub, shrub, tree, shrub, liana, shrub, tr…
glimpse(hr_attr)
## Observations: 62
## Variables: 26
## $ class   <fct> Magnoliopsida, Liliopsida, Magnoliopsida, Magnoliopsida,…
## $ order   <fct> Rosales, Arales, Ranunculales, Rosales, Rosales, Euphorb…
## $ family  <fct> Rosaceae, Araceae, Berberidaceae, Rosaceae, Rosaceae, Th…
## $ genus   <fct> Amelanchier, Arum, Berberis, Cotoneaster, Crataegus, Dap…
## $ species <fct> Amelanchier.ovalis, Arum.italicum, Berberis.vulgaris, Co…
## $ spcode  <fct> Amova, Arita, Bevul, Cogra, Crmon, Dalau, Hehel, Jucom, …
## $ w       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ g       <dbl> 7.3, 9.2, 5.5, 7.0, 9.3, 6.4, 8.4, 8.6, 12.9, 11.5, 8.7,…
## $ f       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ a       <dbl> 0.00010, 0.66000, 14.52000, 0.14500, 0.84500, 0.00011, 1…
## $ geog    <int> 4, 7, 14, 6, 14, 10, 6, 13, 4, 8, 8, 9, 4, 5, 3, 5, 5, 1…
## $ ph      <dbl> 1.0, 0.5, 3.0, 1.0, 6.0, 1.0, 3.0, 10.0, 2.0, 7.0, 9.0, …
## $ pp      <dbl> 0.3333, 0.2121, 0.2424, 0.3030, 0.1515, 0.2727, 0.2424, …
## $ ps      <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pa      <dbl> 0.1515, 0.1515, 0.1212, 0.0909, 0.1515, 0.2424, 0.0606, …
## $ pu      <dbl> 0.4242, 0.5758, 0.2121, 0.5455, 0.0303, 0.3636, 0.4545, …
## $ hab     <fct> climax, climax, climax, climax, climax, climax, climax, …
## $ diet    <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ forag   <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ noct    <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ nativ   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ frlen   <dbl> 7.0, 11.1, 10.4, 7.5, 12.1, 9.4, 7.2, 8.2, 11.3, 9.9, 7.…
## $ fleshy  <fct> Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Yes, Y…
## $ seedm   <dbl> 0.003, 0.038, 0.020, 0.025, 0.124, 0.022, 0.016, 0.011, …
## $ height  <dbl> 1.9, 0.3, 1.2, 1.3, 4.0, 1.2, 3.0, 0.6, 2.8, 0.6, 0.6, 3…
## $ grwform <fct> shrub, herb, shrub, shrub, tree, shrub, liana, shrub, tr…

Here I use the function bip_init_network to initialize a few examples of bipartite networks. The function returns a network object. The equivelent fucntion bip_init_igraph returns an igraph (graph) object.

source("./code/functions/bip_init_network.R")
source("./code/functions/bip_init_igraph.R")

nch.net<- bip_init_network(nch)     # Network object
nch.ig<- bip_init_igraph(nch)       # igraph object
## Loading required package: igraph
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:bipartite':
## 
##     strength
## The following objects are masked from 'package:sna':
## 
##     betweenness, bonpow, closeness, components, degree,
##     dyad.census, evcent, hierarchy, is.connected, neighborhood,
##     triad.census
## The following objects are masked from 'package:network':
## 
##     %c%, %s%, add.edges, add.vertices, delete.edges,
##     delete.vertices, get.edge.attribute, get.edges,
##     get.vertex.attribute, is.bipartite, is.directed,
##     list.edge.attributes, list.vertex.attributes,
##     set.edge.attribute, set.vertex.attribute
## The following object is masked from 'package:vegan':
## 
##     diversity
## The following object is masked from 'package:permute':
## 
##     permute
## The following objects are masked from 'package:dplyr':
## 
##     as_data_frame, groups, union
## The following objects are masked from 'package:purrr':
## 
##     compose, simplify
## The following object is masked from 'package:tidyr':
## 
##     crossing
## The following object is masked from 'package:tibble':
## 
##     as_data_frame
## The following object is masked from 'package:base':
## 
##     union
hr.net<- bip_init_network(hr)       # Network object
hr.ig<- bip_init_igraph(hr)         # igraph object
# Set colors for each mode
col= c("P"= "#FC9272", "A"= "#9ECAE1")
pp<- bip_ggnet(hr.net, as.matrix(hr),
          size=7, shape= "mode", #label= T,
          color= "mode", palette= col, 
          layout.exp= 0.25) + 
          geom_text(aes(label= network.vertex.names(hr.net)),
                        color= "black", size= 3) +
          theme(legend.position="none")                 # Hide legend
pp

Another alternative is to pass the node colors directly, with a vector of node colors that has exactly the same length as the number of nodes in the network:

pp1<- bip_ggnet(nch.net, as.matrix(nch),
                size= 6, color= "mode", label= T, label.size=2,
                palette= c("P"= "indianred3", "A"= "steelblue4")) +
                theme(legend.position="none")           # Hide legend
pp1

pp2<- bip_ggnet(nch.net, as.matrix(nch),
          size= 0,
          shape= "mode", 
          palette= "Set1",
          color= "mode",
          layout.exp= 0.25) +
          geom_point(aes(color= color), size= 8, color= "white") +
          geom_point(aes(color= color), size= 8, alpha= 0.5) +
          geom_point(aes(color= color), size= 6) +
          geom_text(aes(label= network.vertex.names(nch.net)), 
                    color= "black", size= 3.5) + # check_overlap= TRUE
          guides(color= FALSE) +
          theme(legend.position="none")          # Hide legend
pp2

nums<- as.vector(c(1:sum(dim(nch))))
pp3<- bip_ggnet(nch.net, as.matrix(nch),
          size= 0,
          shape= "mode", 
          palette= "Set1",
          color= "mode",
          layout.exp = 0.25) +
          geom_point(aes(color= color), size= 10, color= "white") +
          geom_point(aes(color= color), size= 10, alpha= 0.5) +
          geom_point(aes(color= color), size= 8) +
          geom_text(aes(label= nums), 
                    color= "white", size= 3.5, fontface="bold") + 
          guides(color= FALSE) +
          theme(legend.position="none")          # Hide legend
pp3

Plotting a weighted network with a custom function

An individual-based network, Prunus

# Input the dataset, as adjacency matrix
pm.disp<- read.table("./data/pmah_disp.txt", 
                     na="NA", sep="\t", dec=".", header= TRUE)
pm.attr<- read.table("./data/pmah_attr.txt", 
                     na="NA", sep="\t", dec=".", header= TRUE)

# Saving
save(pm.disp, file="./data/pm.disp.RData")

pm.disp.mat<- as.matrix(pm.disp[,2:22])
row.names(pm.disp.mat)<- pm.disp$X

pru.disp.net<- bip_init_network(pm.disp.mat)
pru.disp.net %e% "nweights"<- 50*(network::get.edge.attribute(pru.disp.net, "weights"))

# Set colors for each mode to setup a palette.
myggnet<- function(net, edge.size= "weights") {   # A net object
            col= c("A"= "lightblue", "P"= "gold")
            pp<- ggnet2(net, size= 6, palette= col, color= "mode",
                    label.size=3, label= T, shape= "mode",
                    edge.label= NULL, edge.size= edge.size, 
                    edge.alpha= 0.5, layout.exp= 0)
            return(pp)
}

myggnet(pru.disp.net, 
        edge.size= 0.025*(network::get.edge.attribute(pru.disp.net, "weights")))
## Warning in guide_merge.legend(init, x[[i]]): Duplicated override.aes is
## ignored.

Dynamic plots of weighted networks

Here we add a value for interaction strength among nodes, so that our networks gets infoermation about the interaction weights. Note that these values are added to the link attributes.

# Load package
require(networkD3)
## Loading required package: networkD3
pm.disp.el<- read.table("./data/pru.disp.el.txt", 
                     na="NA", sep="\t", dec=".", header= TRUE)

# Convert to object suitable for networkD3
pm.disp.el[,1]<- as.character(pm.disp.el[,1]) 
pm.disp.el[,2]<- as.character(pm.disp.el[,2])
pm.disp.el<- as.matrix(pm.disp.el)

# The graph
pm.disp.g<- graph.edgelist(pm.disp.el[,1:2], directed=FALSE)
E(pm.disp.g)$weight<- as.numeric(pm.disp.el[,3]) 

pm.disp.d3 <- igraph_to_networkD3(pm.disp.g)
# pm.disp.d3$nodes$group<- c("A","P","A","A")


# Weighted network
# Plot
pm.disp.nodes<- as.data.frame(pm.disp.d3$nodes$name)
pm.disp.nodes$group<- c(rep("F",22),rep("P",18))
colnames(pm.disp.nodes)<- c("name", "group")

forceNetwork(Links = pm.disp.d3$links, Nodes = pm.disp.nodes,
             Source = 'source', Target = 'target', NodeID = 'name',
             Value='value', Group = "group",
             linkDistance = JS("function(d){return d.value * 15}"),
             linkWidth = JS("function(d) { return Math.sqrt(d.value)/3; }"),
             fontFamily = "sans-serif", fontSize= 12, legend=T, 
             bounded=T, opacityNoHover= 0.5, charge=-30,
             height= 600, width= 600, zoom = TRUE, opacity = 0.65)

The package bipartiteD3 can also be used for easily interact with bipartite networks.

# Plot with bipartiteD3

bipartite_D3(Safariland, PrimaryLab = 'Flowers',
            SecondaryLab = 'Pollinators',
            colouroption = 'brewer', 
            BrewerPalette ='Dark2')
## Warning in RColorBrewer::brewer.pal(n = length(ToColour), name = BrewerPalette): n too large, allowed maximum for palette Dark2 is 8
## Returning the palette you asked for with that many colors
nch.m<- as.matrix(nch)
bipartite_D3(nch.m, PrimaryLab = 'Plants',
            SecondaryLab = 'Frugivores',
            colouroption = 'brewer', 
            BrewerPalette ='Dark2')
## Warning in RColorBrewer::brewer.pal(n = length(ToColour), name = BrewerPalette): n too large, allowed maximum for palette Dark2 is 8
## Returning the palette you asked for with that many colors

Session

sessionInfo()
## R version 3.5.2 (2018-12-20)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Mojave 10.14.5
## 
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices datasets  utils     methods   base     
## 
## other attached packages:
##  [1] networkD3_0.4        igraph_1.2.4.1       ggnet_0.1.0         
##  [4] GGally_1.4.0         scales_1.0.0         bipartiteD3_0.1.0   
##  [7] bipartite_2.11       sna_2.4              network_1.15        
## [10] statnet.common_4.2.0 vegan_2.5-4          lattice_0.20-38     
## [13] permute_0.9-5        forcats_0.3.0        stringr_1.4.0       
## [16] dplyr_0.8.0.1        purrr_0.3.2          readr_1.1.1         
## [19] tidyr_0.8.2          tibble_2.1.1         tidyverse_1.2.1     
## [22] ggplot2_3.1.1        usethis_1.4.0        devtools_2.0.1      
## 
## loaded via a namespace (and not attached):
##  [1] nlme_3.1-137       fs_1.2.6           lubridate_1.7.4   
##  [4] RColorBrewer_1.1-2 httr_1.4.0         rprojroot_1.3-2   
##  [7] tools_3.5.2        backports_1.1.2    utf8_1.1.4        
## [10] R6_2.4.0           lazyeval_0.2.2     mgcv_1.8-26       
## [13] colorspace_1.4-1   withr_2.1.2        tidyselect_0.2.5  
## [16] prettyunits_1.0.2  processx_3.2.1     compiler_3.5.2    
## [19] cli_1.1.0          rvest_0.3.2        xml2_1.2.0        
## [22] desc_1.2.0         callr_3.1.1        digest_0.6.18     
## [25] rmarkdown_1.12     pkgconfig_2.0.2    htmltools_0.3.6   
## [28] sessioninfo_1.1.1  maps_3.3.0         htmlwidgets_1.3   
## [31] rlang_0.3.4        readxl_1.1.0       rstudioapi_0.8    
## [34] jsonlite_1.6       magrittr_1.5       dotCall64_1.0-0   
## [37] Matrix_1.2-15      fansi_0.4.0        Rcpp_1.0.1        
## [40] munsell_0.5.0      stringi_1.4.3      yaml_2.2.0        
## [43] MASS_7.3-51.1      pkgbuild_1.0.2     plyr_1.8.4        
## [46] grid_3.5.2         parallel_3.5.2     crayon_1.3.4      
## [49] haven_1.1.2        hms_0.4.2          knitr_1.22        
## [52] ps_1.3.0           pillar_1.3.1       pkgload_1.0.2     
## [55] glue_1.3.1         evaluate_0.13      remotes_2.0.2     
## [58] modelr_0.1.2       spam_2.2-2         testthat_2.1.1    
## [61] cellranger_1.1.0   gtable_0.3.0       reshape_0.8.8     
## [64] assertthat_0.2.1   r2d3_0.2.2         xfun_0.6          
## [67] broom_0.5.0        coda_0.19-2        memoise_1.1.0     
## [70] fields_9.7         cluster_2.0.7-1

References

1. Dormann CF, Gruber B, Fruend J. 2008. Introducing the bipartite package: Analysing ecological networks. R News. 8(2):8–11

2. Terry C. 2018. BipartiteD3: Interactive bipartite graphs. pp. ed.

footer.utf8.md


Licensing Creative Commons License
CC

Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
2018 - Pedro Jordano